home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / ideas / track.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  20KB  |  985 lines

  1. /*
  2.  * Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. #include <gl.h>
  18. #include <device.h>
  19. #include <math.h>
  20. #include <sys/time.h>
  21. #include <stdio.h>
  22. #include "objects.h"
  23.  
  24. #define X 0
  25. #define Y 1
  26. #define Z 2
  27.  
  28. #define DEG *3.14159265359/180.0
  29. #define RAD *180.0/3.14159265359
  30.  
  31. float move_speed;        /* Spline distance per second */
  32. static long menu;        /* The pop up menu */
  33.  
  34. #define O_RESTART    1
  35. #define O_QUIT        2
  36. #define O_SLOW        3
  37. #define O_MEDIUM    4
  38. #define O_FAST        5
  39. #define O_SUPER_FAST    6
  40.  
  41. #define O_NOMS        7
  42. #define O_4MS        8
  43. #define O_8MS        9
  44. #define O_16MS        10
  45.  
  46. float idmat[4][4] = {
  47.     {1.0, 0.0, 0.0, 0.0},
  48.     {0.0, 1.0, 0.0, 0.0},
  49.     {0.0, 0.0, 1.0, 0.0},
  50.     {0.0, 0.0, 0.0, 1.0},
  51. };
  52. float light1[] = {
  53.     AMBIENT, 0.0, 0.0, 0.0, 
  54.     LCOLOR,   1.0, 1.0, 1.0, 
  55.     POSITION, 0.0, 1.0, 0.0, 0.0, 
  56.     LMNULL
  57. };
  58. float light2[] = {
  59.     AMBIENT, 0.0, 0.0, 0.0, 
  60.     LCOLOR,   0.3, 0.3, 0.5, 
  61.     POSITION, -1.0, 0.0, 0.0, 0.0, 
  62.     LMNULL
  63. };
  64. float light3[] = {
  65.     AMBIENT, 0.2, 0.2, 0.2, 
  66.     LCOLOR,   0.2, 0.2, 0.2, 
  67.     POSITION, 0.0, -1.0, 0.0, 0.0, 
  68.     LMNULL
  69. };
  70. float lmodel[] = {
  71.     AMBIENT, 0.3,  0.3, 0.3, 
  72.     LOCALVIEWER, 0.0, 
  73.     LMNULL
  74. };
  75. float mat_logo[] = {
  76.     AMBIENT,    0.1, 0.1, 0.1,
  77.     DIFFUSE,    0.5, 0.4, 0.7,
  78.     SPECULAR,    1.0, 1.0, 1.0,
  79.     SHININESS,    30.0,
  80.     LMNULL,
  81. };
  82. float mat_holder_base[] = {
  83.     AMBIENT,    0.0, 0.0, 0.0,
  84.     DIFFUSE,    0.6, 0.6, 0.6,
  85.     SPECULAR,    0.8, 0.8, 0.8,
  86.     SHININESS,    30.0,
  87.     LMNULL,
  88. };
  89. float mat_holder_rings[] = {
  90.     AMBIENT,    0.0, 0.0, 0.0,
  91.     DIFFUSE,    0.9, 0.8, 0.0,
  92.     SPECULAR,    1.0, 1.0, 1.0,
  93.     SHININESS,    30.0,
  94.     LMNULL,
  95. };
  96. float mat_hemisphere[] = {
  97.     AMBIENT,    0.0, 0.0, 0.0,
  98.     DIFFUSE,    1.0, 0.2, 0.2,
  99.     SPECULAR,    0.5, 0.5, 0.5,
  100.     SHININESS,    20.0,
  101.     LMNULL,
  102. };
  103. init_materials() {
  104.  
  105.     lmdef(DEFMATERIAL, MAT_LOGO, 0, mat_logo);
  106.     lmdef(DEFMATERIAL, MAT_HOLDER_BASE, 0, mat_holder_base);
  107.     lmdef(DEFMATERIAL, MAT_HOLDER_RINGS, 0, mat_holder_rings);
  108.     lmdef(DEFMATERIAL, MAT_HEMISPHERE, 0, mat_hemisphere);
  109. }
  110. #define HALFTONE 1
  111.  
  112. unsigned short halftone[] = { 0x5555, 0xaaaa, 0x5555, 0xaaaa,
  113.     0x5555, 0xaaaa, 0x5555, 0xaaaa,
  114.     0x5555, 0xaaaa, 0x5555, 0xaaaa,
  115.     0x5555, 0xaaaa, 0x5555, 0xaaaa };
  116. /*
  117. unsigned short halftone[] = { 0xeeee, 0xffff, 0xbbbb, 0xffff,
  118.     0xeeee, 0xffff, 0xbbbb, 0xffff,
  119.     0xeeee, 0xffff, 0xbbbb, 0xffff,
  120.     0xeeee, 0xffff, 0xbbbb, 0xffff };
  121. */
  122.  
  123. short dev, val;
  124.  
  125. float Time=0.0;
  126.  
  127. float tmplight[] = {
  128.     POSITION, 0.0, 0.0, 0.0, 0.0, LMNULL
  129. };
  130.  
  131. float tv[4][4] = {
  132.     {1.0, 0.0, 0.0, 0.0},
  133.     {0.0, 1.0, 0.0, -1.0},
  134.     {0.0, 0.0, 1.0, 0.0},
  135.     {0.0, 0.0, 0.0, 0.0},
  136. };
  137.  
  138. #define TABLERES 12
  139.  
  140. float pcr, pcg, pcb, pca;
  141.  
  142. typedef float vector[3];
  143. typedef vector parameter[4];
  144.  
  145. vector table_points[TABLERES+1][TABLERES+1];
  146. int tablecolors[TABLERES+1][TABLERES+1];
  147.  
  148. vector paper_points[4] = {
  149.     {-0.8, 0.0, 0.4},
  150.     {-0.2, 0.0, -1.4},
  151.     {1.0, 0.0, -1.0},
  152.     {0.4, 0.0, 0.8},
  153. };
  154.  
  155. float dot(vector, vector);
  156.  
  157. #define TIME 15
  158. #define START_TIME 0.6
  159.  
  160. vector light_pos_ctl[] = {
  161.  
  162.     {0.0, 1.8, 0.0},
  163.     {0.0, 1.8, 0.0},
  164.     {0.0, 1.6, 0.0},
  165.  
  166.     {0.0, 1.6, 0.0},
  167.     {0.0, 1.6, 0.0},
  168.     {0.0, 1.6, 0.0},
  169.     {0.0, 1.4, 0.0},
  170.  
  171.     {0.0, 1.3, 0.0},
  172.     {-0.2, 1.5, 2.0},
  173.     {0.8, 1.5, -0.4},
  174.     {-0.8, 1.5, -0.4},
  175.  
  176.     {0.8, 2.0, 1.0},
  177.     {1.8, 5.0, -1.8},
  178.     {8.0, 10.0, -4.0},
  179.     {8.0, 10.0, -4.0},
  180.     {8.0, 10.0, -4.0},
  181. };
  182.  
  183. vector logo_pos_ctl[] = {
  184.  
  185.     {0.0, -0.5, 0.0},
  186.  
  187.     {0.0, -0.5, 0.0},
  188.     {0.0, -0.5, 0.0},
  189.  
  190.     {0.0, -0.5, 0.0},
  191.     {0.0, -0.5, 0.0},
  192.     {0.0, -0.5, 0.0},
  193.     {0.0, 0.0, 0.0},
  194.  
  195.     {0.0, 0.6, 0.0},
  196.     {0.0, 0.75, 0.0},
  197.     {0.0, 0.8, 0.0},
  198.     {0.0, 0.8, 0.0},
  199.  
  200.     {0.0, 0.5, 0.0},
  201.     {0.0, 0.5, 0.0},
  202.     {0.0, 0.5, 0.0},
  203.     {0.0, 0.5, 0.0},
  204.     {0.0, 0.5, 0.0},
  205. };
  206.  
  207.  
  208. vector logo_rot_ctl[] = {
  209.  
  210.     {0.0, 0.0, -18.4},
  211.  
  212.     {0.0, 0.0, -18.4},
  213.     {0.0, 0.0, -18.4},
  214.  
  215.     {0.0, 0.0, -18.4},
  216.     {0.0, 0.0, -18.4},
  217.     {0.0, 0.0, -18.4},
  218.     {0.0, 0.0, -18.4},
  219.     {0.0, 0.0, -18.4},
  220.  
  221. /*    {90.0, 0.0, -90.0},
  222.     {180.0, 180.0, 90.0}, */
  223.     {240.0, 360.0, 180.0},
  224.     {90.0, 180.0, 90.0},
  225.  
  226.     {11.9, 0.0, -18.4},
  227.     {11.9, 0.0, -18.4},
  228.     {11.9, 0.0, -18.4},
  229.     {11.9, 0.0, -18.4},
  230.     {11.9, 0.0, -18.4},
  231. };
  232.  
  233.  
  234. vector view_from_ctl[] = {
  235.  
  236.     {-1.0, 1.0, -4.0},
  237.  
  238.     {-1.0, -3.0, -4.0},    /* 0 */
  239.     {-3.0, 1.0, -3.0},    /* 1 */
  240.  
  241.     {-1.8, 2.0, 5.4},    /* 2 */
  242.     {-0.4, 2.0, 1.2},    /* 3 */
  243.     {-0.2, 1.5, 0.6},    /* 4 */
  244.     {-0.2, 1.2, 0.6},    /* 5 */
  245.  
  246.     {-0.8, 1.0, 2.4},    /* 6 */
  247.     {-1.0, 2.0, 3.0},    /* 7 */
  248.     {0.0, 4.0, 3.6},    /* 8 */
  249.     {-0.8, 4.0, 1.2},    /* 9 */
  250.  
  251.     {-0.2, 3.0, 0.6},    /* 10 */
  252.     {-0.1, 2.0, 0.3},    /* 11 */
  253.     {-0.1, 2.0, 0.3},    /* 12 */
  254.     {-0.1, 2.0, 0.3},    /* 13 */
  255.     {-0.1, 2.0, 0.3},    /* 13 */
  256.  
  257.  
  258. };
  259.  
  260. vector view_to_ctl[] = {
  261.  
  262.     {-1.0, 1.0, 0.0},
  263.  
  264.     {-1.0, -3.0, 0.0},
  265.     {-1.0, 1.0, 0.0},
  266.  
  267.     {0.1, 0.0, -0.3},
  268.     {0.1, 0.0, -0.3},
  269.     {0.1, 0.0, -0.3},
  270.     {0.0, 0.2, 0.0},
  271.  
  272.     {0.0, 0.6, 0.0},
  273.     {0.0, 0.8, 0.0},
  274.     {0.0, 0.8, 0.0},
  275.     {0.0, 0.8, 0.0},
  276.  
  277.     {0.0, 0.8, 0.0},
  278.     {0.0, 0.8, 0.0},
  279.     {0.0, 0.8, 0.0},
  280.     {0.0, 0.8, 0.0},
  281.     {0.0, 0.8, 0.0},
  282.  
  283. };
  284.  
  285.  
  286. vector view_from, view_to, light_pos, logo_pos, logo_rot;
  287.  
  288. parameter *view_from_spline, *view_to_spline,
  289.       *light_pos_spline, *logo_pos_spline,
  290.       *logo_rot_spline;
  291.  
  292. parameter *calc_spline_params(vector *, int);
  293.  
  294. double a3, a4;
  295.  
  296. void ideas_usage(void)
  297. {
  298.     fprintf(stderr, "Usage: ideas [-a]\n");
  299. }
  300.  
  301. main(argc, argv)
  302. int    argc;
  303. char    *argv[];
  304. {
  305.     float x, y, z, c;
  306.     int pick;
  307.     int loops;
  308.     int i;
  309.     int auto_run;    /* If set, then automatically run forever */
  310.     struct timeval start;
  311.     struct timeval current;
  312.     float timediff;    
  313.     float timeoffset;    /* Used to compute timing */
  314.     float new_speed;    /* Set new animation speed? */
  315.     int resetclock;    /* Reset the clock? */
  316.     int timejerk;    /* Set to indicate time jerked! (menu pulled down) */
  317.  
  318.     /* .4 spline distance per second by default */
  319.     move_speed=.4;
  320.     new_speed=.4;
  321.     timeoffset=START_TIME;
  322.  
  323.  
  324.     auto_run = 0;    /* Don't automatically run forever */
  325.     for (i = 1; i < argc; i++) {
  326.     if (argv[i][0] != '-') {
  327.         break;
  328.     }
  329.  
  330.     switch(argv[i][1]) {
  331.         case 'a':    /* Keep running forever */
  332.         auto_run = 1;
  333.         break;
  334.         default:
  335.         ideas_usage();
  336.         break;
  337.     }
  338.     }
  339.  
  340.     initialize(argv[0]);
  341.  
  342.     loops = 0;
  343.     Time = timeoffset;
  344.     resetclock = 1;
  345.     timejerk = 0;
  346.     while (TRUE) {
  347.     if ((Time) > (TIME*1.0)-3.0) Time = TIME*1.0-3.001;
  348.  
  349.     while(qtest()) {
  350.  
  351.         switch(dev=qread(&val)) {
  352.           case REDRAW:
  353.         timejerk = 1;
  354.         reshapeviewport();
  355.         break;
  356.  
  357.           case ESCKEY:
  358.         if (val) break;    /* Ignore down, exit up */
  359.           case WINQUIT:
  360.         gexit();
  361.         exit(0);
  362.  
  363.           case LEFTMOUSE:
  364.         if (!val) {
  365.             resetclock = 1;
  366.         }
  367.         break;
  368.           case RIGHTMOUSE:
  369.         timejerk = 1;
  370.         switch(dopup(menu)) {
  371.           case O_NOMS:        /* No multi sampling */
  372.             zbsize(32);
  373.             mssize(0,0,0);
  374.             gconfig();
  375.             break;
  376.           case O_4MS:        /* 4 multi samples */
  377.             zbsize(0);
  378.             mssize(4,32,0);
  379.             gconfig();
  380.             break;
  381.           case O_8MS:        /* 8 multi samples */
  382.             zbsize(0);
  383.             mssize(8,32,0);
  384.             gconfig();
  385.             break;
  386.           case O_16MS:        /* 16 multi samples */
  387.             zbsize(0);
  388.             mssize(16,32,0);
  389.             gconfig();
  390.             break;
  391.           case O_SLOW:        /* Slow */
  392.             new_speed = 0.2;
  393.             break;
  394.           case O_MEDIUM:    /* Medium */
  395.             new_speed = 0.4;
  396.             break;
  397.           case O_FAST:        /* Fast */
  398.             new_speed = 0.7;
  399.             break;
  400.           case O_SUPER_FAST:    /* Really fast! */
  401.             new_speed = 1.0;
  402.             break;
  403.           case O_RESTART:    /* Restart */
  404.             resetclock = 1;
  405.             break;
  406.           case O_QUIT:        /* Quit */
  407.             gexit();
  408.             exit(0);
  409.             break;
  410.           default:
  411.             break;
  412.         }
  413.         break;
  414.         }
  415.     }
  416.  
  417.     calc_spline(view_from, view_from_spline, Time);
  418.     calc_spline(view_to, view_to_spline, Time);
  419.     calc_spline(light_pos, light_pos_spline, Time);
  420.     calc_spline(logo_pos, logo_pos_spline, Time);
  421.     calc_spline(logo_rot, logo_rot_spline, Time);
  422.  
  423.     if (auto_run) {
  424.         loops++;
  425.         if (loops == 650) {
  426.         resetclock = 1;
  427.         loops = 0;
  428.         }
  429.     }
  430.  
  431.     tmplight[1] = light_pos[X]-logo_pos[X];
  432.     tmplight[2] = light_pos[Y]-logo_pos[Y];
  433.     tmplight[3] = light_pos[Z]-logo_pos[Z];
  434.  
  435.     lmdef(DEFLIGHT, 1, 0, tmplight);
  436.  
  437.     tv[0][0] = tv[1][1] = tv[2][2] = light_pos[Y];
  438.  
  439.     RGBcolor(0, 0, 0);
  440.     clear(); zclear();
  441.  
  442.     mmode(MSINGLE);
  443.  
  444.     perspective(450, 5.0/4.0, 0.5, 20.0);
  445.     lookat(view_from[X], view_from[Y], view_from[Z],
  446.            view_to[X], view_to[Y], view_to[Z], 0);
  447.  
  448.     if (view_from[Y] > 0.0) draw_table();
  449.  
  450.     zbuffer(FALSE);
  451.  
  452.     if (logo_pos[Y]<0.0) {
  453.  
  454.         if (logo_pos[Y]>-0.33) {
  455.         c = 1.0 - (logo_pos[Y])/-0.33;
  456.         pca /= 4.0;
  457.         RGBcolor((int)(128.0*(1.0-c)*0.5 + 255.0*pca*c),
  458.              (int)(102.0*(1.0-c)*0.5 + 255.0*pca*c), 
  459.              (int)(179.0*(1.0-c)*0.5 + 200.0*pca*c));
  460.         } else {
  461.         RGBcolor(128/2, 102/2, 179/2);
  462.         }
  463.  
  464.         pushmatrix();
  465.         scale(0.04, 0.0, 0.04);
  466.         rotate(-900, 'x');
  467.         rotate((int)(10.0*logo_rot[Z]), 'z');
  468.         rotate((int)(10.0*logo_rot[Y]), 'y');
  469.         rotate((int)(10.0*logo_rot[X]), 'x');
  470.         rotate(353, 'x');
  471.         rotate(450, 'y');
  472.         draw_logo_shadow();
  473. /*        draw_logo_line();*/
  474.         popmatrix();
  475.     }
  476.  
  477.     if (logo_pos[Y]>0.0) {
  478.  
  479.         pushmatrix();
  480.  
  481.         if (logo_pos[Y]<0.33) {
  482.         pca /= 4.0;
  483.         c = 1.0 - (logo_pos[Y])/0.33;
  484.         RGBcolor((int)(255.0*pca*c),
  485.              (int)(255.0*pca*c),
  486.              (int)(200.0*pca*c));
  487.         } else {
  488.         RGBcolor(0, 0, 0);
  489.         }
  490.  
  491.         translate(light_pos[X], light_pos[Y], light_pos[Z]);
  492.         multmatrix(tv);
  493.         translate(-light_pos[X]+logo_pos[X],
  494.               -light_pos[Y]+logo_pos[Y],
  495.               -light_pos[Z]+logo_pos[Z]);
  496.         scale(0.04, 0.04, 0.04);
  497.         rotate(-900, 'x');
  498.         rotate((int)(10.0*logo_rot[Z]), 'z');
  499.         rotate((int)(10.0*logo_rot[Y]), 'y');
  500.         rotate((int)(10.0*logo_rot[X]), 'x');
  501.         rotate(353, 'x');
  502.         rotate(450, 'y');
  503.         setpattern(HALFTONE);
  504.         draw_logo_shadow();
  505.         setpattern(0);
  506.         popmatrix();
  507.  
  508.     }
  509.     zbuffer(TRUE);
  510.  
  511.     mmode(MVIEWING);
  512.     perspective(450, 5.0/4.0, 0.5, 20.0);
  513.     loadmatrix(idmat);
  514.     lookat(view_from[X], view_from[Y], view_from[Z],
  515.            view_to[X], view_to[Y], view_to[Z], 0);
  516.  
  517.     lmbind(LIGHT0, 3);
  518.     lmbind(LIGHT1, 2);
  519.  
  520.     lmbind(MATERIAL, MAT_HOLDER_RINGS);
  521.  
  522.     pushmatrix();
  523.     translate(light_pos[X], light_pos[Y], light_pos[Z]);
  524.     scale(0.1, 0.1, 0.1);
  525.  
  526.     x = light_pos[X] - logo_pos[X];
  527.     y = light_pos[Y] - logo_pos[Y];
  528.     z = light_pos[Z] - logo_pos[Z];
  529.  
  530.     if (x!=0.0) {
  531.         a3 = -atan2(z, x)*10.0 RAD;
  532.     } else a3 = 0.0;
  533.  
  534.     a4 = -atan2(sqrt(x*x + z*z), y)*10.0 RAD;
  535.  
  536.     rotate((int)a3, 'y');
  537.     rotate((int)a4, 'z');
  538.  
  539.     rotate(-900, 'x');
  540.     draw_hemisphere();
  541.     popmatrix();
  542.  
  543.     lmbind(LIGHT0, 1);
  544.     lmbind(LIGHT1, 0);
  545.  
  546.     if (logo_pos[Y] > -0.33) {
  547.         pushmatrix();
  548.         translate(logo_pos[X], logo_pos[Y], logo_pos[Z]);
  549.         scale(0.04, 0.04, 0.04);
  550.         rotate(-900, 'x');
  551.         rotate((int)(10.0*logo_rot[Z]), 'z');
  552.         rotate((int)(10.0*logo_rot[Y]), 'y');
  553.         rotate((int)(10.0*logo_rot[X]), 'x');
  554.         rotate(353, 'x');
  555.         rotate(450, 'y');
  556.         lmbind(LMODEL, 1);
  557.         draw_logo();
  558.         lmbind(LMODEL, 0);
  559.         popmatrix();
  560.     }
  561.  
  562.     if (view_from[Y] < 0.0) draw_under_table();
  563.  
  564.     swapbuffers();
  565.  
  566.     /* Time jerked -- adjust clock appropriately */
  567.     if (timejerk) {
  568.         timejerk = 0;
  569.         timeoffset = Time;
  570.         gettimeofday(&start, NULL);
  571.     }
  572.  
  573.     /* Reset our timer */
  574.     if (resetclock) {
  575.         resetclock = 0;
  576.         timeoffset = START_TIME;
  577.         gettimeofday(&start, NULL);
  578.     }
  579.  
  580.     /* Compute new time */
  581.     gettimeofday(¤t, NULL);
  582.     timediff = (current.tv_sec - start.tv_sec) + 
  583.         (current.tv_usec - start.tv_usec) / 1000000.0;
  584.     Time = timediff * move_speed + timeoffset;
  585.  
  586.     /* Adjust to new speed */
  587.     if (new_speed != move_speed) {
  588.         move_speed = new_speed;
  589.         timeoffset = Time;
  590.         gettimeofday(&start, NULL);
  591.     }
  592.     }
  593. }
  594.  
  595. add_pick (menu, pickstr, rval)
  596. int menu;
  597. char *pickstr;
  598. int rval;
  599. {
  600.     char pstr[60];
  601.  
  602.     sprintf (pstr, "%s%%x%0d", pickstr, rval);
  603.     addtopup (menu, pstr);
  604. }
  605.  
  606. add_submenu (menu, pickstr, menuid)
  607. int menu;
  608. char *pickstr;
  609. int menuid;
  610. {
  611.     char pstr[32];
  612.  
  613.     sprintf (pstr, "%s%%m", pickstr);
  614.     addtopup (menu, pstr, menuid);
  615. }
  616.  
  617.  
  618. initialize(title)
  619. char *title;
  620. {
  621.     char *t, *strrchr();
  622.     int multiAvail;
  623.     static long speedmenu;
  624.     static long msmenu;
  625.  
  626.     keepaspect(5, 4);
  627.     winopen((t=strrchr(title, '/')) != NULL ? t+1 : title);
  628.  
  629.     if (getgdesc(GD_BITS_NORM_DBL_RED) == 0) {
  630.     system("inform 'Your system must support RGB mode to run ideas'");
  631.     exit(1);
  632.     }
  633.     if (getgdesc(GD_BITS_NORM_ZBUFFER) == 0) {
  634.     system("inform 'Your system must have a z-buffer to run ideas'");
  635.     exit(1);
  636.     }
  637.  
  638.     doublebuffer();
  639.     RGBmode();
  640.     subpixel(TRUE);
  641.     gconfig();
  642.  
  643.     multiAvail = 0;
  644.     if (getgdesc(GD_MULTISAMPLE) == 1) {
  645.  
  646.     zbsize(0);
  647.     mssize(16,32,0);
  648.     gconfig();
  649.  
  650.     if (getgconfig(GC_MS_SAMPLES) == 16) multiAvail = 16;
  651.     else if (getgconfig(GC_MS_SAMPLES) == 8) multiAvail = 8;
  652.     else if (getgconfig(GC_MS_SAMPLES) == 4) multiAvail = 4;
  653.     else if (getgconfig(GC_MS_SAMPLES) <= 4) {
  654.         multiAvail = 0;
  655.         zbsize(32);
  656.         mssize(0,0,0);
  657.         gconfig();
  658.     } 
  659.     } 
  660.  
  661.     qdevice(LEFTMOUSE);
  662.     qdevice(RIGHTMOUSE);
  663.     qdevice(ESCKEY);
  664.     qdevice(WINQUIT);
  665.     qdevice(WINSHUT);
  666.  
  667.     menu = defpup("Ideas %t");
  668.  
  669.     add_pick(menu, "Restart", O_RESTART);
  670.  
  671.  
  672.     speedmenu = defpup("Speed %t");
  673.     add_pick(speedmenu, "Slow", O_SLOW);
  674.     add_pick(speedmenu, "Medium", O_MEDIUM);
  675.     add_pick(speedmenu, "Fast", O_FAST);
  676.     add_pick(speedmenu, "Super Fast", O_SUPER_FAST);
  677.     add_submenu(menu, "Speed", speedmenu);
  678.  
  679.     if (multiAvail > 0) {
  680.     msmenu = defpup("Multi Sampling %t");
  681.     add_pick(msmenu, "None", O_NOMS);
  682.     if (multiAvail >= 4 ) add_pick(msmenu, "4 Samples", O_4MS);
  683.     if (multiAvail >= 8 ) add_pick(msmenu, "8 Samples", O_8MS);
  684.     if (multiAvail >= 16 ) add_pick(msmenu, "16 Samples", O_16MS);
  685.     add_submenu(menu, "Multi Sampling", msmenu);
  686.     }
  687.  
  688.     add_pick(menu, "Quit", O_QUIT);
  689.  
  690.     defpattern(HALFTONE, 16, halftone);
  691.  
  692.     /* lsetdepth(0x0, 0x7fffff); */
  693.     lsetdepth((getgdesc(GD_ZMIN)), (getgdesc(GD_ZMAX)));
  694.     lmdef(DEFLIGHT, 1, 0, light1);
  695.     lmdef(DEFLIGHT, 2, 0, light2);
  696.     lmdef(DEFLIGHT, 3, 0, light3);
  697.     lmdef(DEFLMODEL, 1, 0, lmodel);
  698.  
  699.     init_materials();
  700.  
  701.     build_table();
  702.  
  703.     view_from_spline = calc_spline_params(view_from_ctl, TIME);
  704.     view_to_spline = calc_spline_params(view_to_ctl, TIME);
  705.     light_pos_spline = calc_spline_params(light_pos_ctl, TIME);
  706.     logo_pos_spline = calc_spline_params(logo_pos_ctl, TIME);
  707.     logo_rot_spline = calc_spline_params(logo_rot_ctl, TIME);
  708.  
  709.     perspective(450, 5.0/4.0, 0.5, 20.0);
  710.  
  711.     mmode(MVIEWING);
  712. }
  713.  
  714.  
  715. build_table() {
  716.  
  717.     float i, j;
  718.  
  719.     for (j=0.0; j<=TABLERES*1.0; j+=1.0) {
  720.     for (i=0.0; i<=TABLERES*1.0; i+=1.0) {
  721.         table_points[(int)j][(int)i][Z] = (i-TABLERES*1.0/2.0)/2.0;
  722.         table_points[(int)j][(int)i][X] = (j-TABLERES*1.0/2.0)/2.0;
  723.         table_points[(int)j][(int)i][Y] = 0.0;
  724.     }
  725.     }
  726. }
  727.  
  728.  
  729. draw_table() {
  730.  
  731.     float x, z, c;
  732.     int i, j;
  733.     int k, l;
  734.     float m, n;
  735.     float ov[3], lv[3];
  736.  
  737.     zbuffer(FALSE);
  738.  
  739.     ov[X] = light_pos[X]-logo_pos[X];
  740.     ov[Y] = light_pos[Y]-logo_pos[Y];
  741.     ov[Z] = light_pos[Z]-logo_pos[Z];
  742.  
  743.     normalize(ov);
  744.  
  745.     for (j=0; j<=TABLERES; j++) {
  746.     for (i=0; i<=TABLERES; i++) {
  747.         lv[X] = light_pos[X] - table_points[j][i][X];
  748.         lv[Y] = light_pos[Y] - table_points[j][i][Y];
  749.         lv[Z] = light_pos[Z] - table_points[j][i][Z];
  750.         normalize(lv);
  751.         if ((c = dot(lv, ov))<0.0) c = 0.0;
  752.         c = c * c * c * lv[Y] * 255.0;
  753.         /* fade */
  754.         if ((Time>TIME-5.0) && (Time<TIME-3.0)) 
  755.         c *= 1.0 - (Time-(TIME-5.0)) * 0.5;
  756.  
  757.         tablecolors[j][i] = (int)c;
  758.     }
  759.     }
  760.  
  761.  
  762.     for (l=0; l<TABLERES; l++) {
  763.  
  764.     bgntmesh();
  765.     for (k=0; k<=TABLERES; k++) {
  766.  
  767.         RGBcolor(tablecolors[l][k],
  768.              tablecolors[l][k],
  769.              tablecolors[l][k]);
  770.         v3f(table_points[l][k]);
  771.  
  772.         RGBcolor(tablecolors[l+1][k],
  773.              tablecolors[l+1][k],
  774.              tablecolors[l+1][k]);
  775.         v3f(table_points[l+1][k]);
  776.  
  777.     }
  778.     endtmesh();
  779.     }
  780.  
  781.     if (logo_pos[Y]>-0.33 && logo_pos[Y]<0.33) {
  782.     zbuffer(TRUE);
  783.     }
  784.  
  785.     pca = 0.0;
  786.     bgnpolygon();
  787.     for (i=0; i<4; i++) {
  788.     lv[X] = light_pos[X] - paper_points[i][X];
  789.     lv[Y] = light_pos[Y] - paper_points[i][Y];
  790.     lv[Z] = light_pos[Z] - paper_points[i][Z];
  791.     normalize(lv);
  792.     if ((c = dot(lv, ov))<0.0) c = 0.0;
  793.     c = c * c * c * lv[Y];
  794.     /* fade */
  795.     if ((Time>TIME-5.0) && (Time<TIME-3.0)) 
  796.         c *= 1.0 - (Time-(TIME-5.0)) * 0.5;
  797.  
  798.     pcr = c * 255; pcg = c * 255; pcb = c * 200;
  799.     pca += c;
  800.     RGBcolor((int)pcr, (int)pcg, (int)pcb);
  801.     v3f(paper_points[i]);
  802.     }
  803.     endpolygon();
  804.  
  805. /*  RGBcolor(0, 200, 255);
  806.     for (m = 0.4; m>-1.4; m -= 0.33) {
  807.     move(-0.8+(m-4.0)/3.0, 0.0, m);
  808.     draw(1.2-0.8+(m-4.0)/3.0, 0.0, m+0.4);
  809.     }
  810. */
  811.  
  812.  
  813.     zbuffer(FALSE);
  814.  
  815.     pushmatrix();
  816.  
  817.     rotate(-184, 'y');
  818.  
  819.     translate(-0.3, 0.0, -0.8);
  820.  
  821.     rotate(-900, 'x');
  822.  
  823.     scale(0.015, 0.015, 0.015);
  824.  
  825.     if (Time>TIME*1.0-5.0) {
  826.     c = (Time-(TIME*1.0-5.0))/2.0;
  827.     RGBcolor((int)(c*255.0), (int)(c*255.0), (int)(c*255.0));
  828.     } else RGBcolor(0, 0, 0);
  829.  
  830.     draw_i();
  831.     translate(3.0, 0.0, 0.0);
  832.  
  833.     draw_d();
  834.     translate(6.0, 0.0, 0.0);
  835.  
  836.     draw_e();
  837.     translate(5.0, 0.0, 0.0);
  838.  
  839.     draw_a();
  840.     translate(6.0, 0.0, 0.0);
  841.  
  842.     draw_s();
  843.     translate(10.0, 0.0, 0.0);
  844.  
  845.     draw_i();
  846.     translate(3.0, 0.0, 0.0);
  847.  
  848.     draw_n();
  849.     translate(-31.0, -13.0, 0.0);
  850.  
  851.     draw_m();
  852.     translate(10.0, 0.0, 0.0);
  853.  
  854.     draw_o();
  855.     translate(5.0, 0.0, 0.0);
  856.  
  857.     draw_t();
  858.     translate(4.0, 0.0, 0.0);
  859.  
  860.     draw_i();
  861.     translate(3.5, 0.0, 0.0);
  862.  
  863.     draw_o();
  864.     translate(5.0, 0.0, 0.0);
  865.  
  866.     draw_n();
  867.  
  868.     popmatrix();
  869.  
  870.     zbuffer(TRUE);
  871.  
  872.  
  873. }
  874.  
  875.  
  876.  
  877. draw_under_table() {
  878.  
  879.     int k, l;
  880.  
  881.     zbuffer(FALSE);
  882.  
  883.  
  884.     RGBcolor(0, 0, 0);
  885.  
  886.     for (l=0; l<TABLERES; l++) {
  887.  
  888.     bgntmesh();
  889.     for (k=0; k<=TABLERES; k++) {
  890.  
  891.         v3f(table_points[l][k]);
  892.         v3f(table_points[l+1][k]);
  893.  
  894.     }
  895.     endtmesh();
  896.     }
  897.  
  898.     zbuffer(TRUE);
  899.  
  900. }
  901.  
  902.  
  903.  
  904. calc_spline(v, params, Time)
  905. vector v;
  906. parameter *params;
  907. float Time;
  908. {
  909.  
  910.     float t, tt;
  911.     int i, j;
  912.  
  913.     tt = t = Time - (float)((int)Time);
  914.  
  915.     for (i=0; i<3; i++) {
  916.  
  917.  
  918.     v[i] = params[(int)Time][3][i] +
  919.            params[(int)Time][2][i] * t +
  920.            params[(int)Time][1][i] * t * t +
  921.            params[(int)Time][0][i] * t * t * t;
  922.     }
  923.  
  924. }
  925.  
  926.  
  927. parameter *calc_spline_params(ctl_pts, n)
  928. vector *ctl_pts;
  929. int n;
  930. {
  931.  
  932.     int i, j;
  933.     parameter *params;
  934.  
  935.     if (n<4) {
  936.     fprintf(stderr,
  937.         "calc_spline_params: not enough control points\n");
  938.     return (NULL);
  939.     }
  940.  
  941.     params = (parameter *)malloc(sizeof(parameter) * (n-3));
  942.  
  943.     for (i=0; i<n-3; i++) {
  944.  
  945.     for (j=0; j<3; j++) {
  946.  
  947.         params[i][3][j] = ctl_pts[i+1][j];
  948.         params[i][2][j] = ctl_pts[i+2][j] - ctl_pts[i][j];
  949.         params[i][1][j] =  2.0 * ctl_pts[i][j] +
  950.                   -2.0 * ctl_pts[i+1][j] +
  951.                    1.0 * ctl_pts[i+2][j] +
  952.                   -1.0 * ctl_pts[i+3][j];
  953.         params[i][0][j] = -1.0 * ctl_pts[i][j] +
  954.                    1.0 * ctl_pts[i+1][j] +
  955.                   -1.0 * ctl_pts[i+2][j] +
  956.                    1.0 * ctl_pts[i+3][j];
  957.  
  958.     }
  959.     }
  960.  
  961.     return (params);
  962. }
  963.  
  964.  
  965. normalize(v)
  966. vector v;
  967. {
  968.     float r;
  969.  
  970.     r = sqrt(v[X]*v[X] + v[Y]*v[Y] + v[Z]*v[Z]);
  971.  
  972.     v[X] /= r;
  973.     v[Y] /= r;
  974.     v[Z] /= r;
  975. }
  976.  
  977.  
  978. float dot(v1, v2)
  979. vector v1, v2;
  980. {
  981.  
  982.     return v1[X]*v2[X]+v1[Y]*v2[Y]+v1[Z]*v2[Z];
  983. }
  984.  
  985.